/**
 * Created by IntelliJ IDEA.
 * User: ��ΰ
 * Date: 2011-12-20
 */
package com.rocksea.app.rslib;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Collections;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONTokener;

import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PaintFlagsDrawFilter;
import android.util.Log;

class JyGradeStruct {
	short nGrade; // ���Լ���
	short nDirect; // ���Է��򣬼���/ж��
	float fQGrade; // ��������ѹ��
	short nTime; // ����������ʱʱ��
	short nTotalTime; // �ۼ���ʱʱ��
	float fSInGrade; // ������ʼλ��
	float fSEnd; // ��������λ��
	ArrayList<JyRecordStruct> RecordList; // �������еĲ�����¼
}

class JyRecordStruct {
	short nGrade; // ���Լ���
	short nIndex; // ������������
	Timestamp SampleTime; // ����ʱ��
	float fQGrade; // ��������ѹ��
	short nDirect; // ���Է��򣬼���/ж��
	short nTimeCount; // ����������ʱ
	float fQ; // ʵ��ѹ��
	float fP; // ʵ��ѹǿ
	float[] fS; // ʵ��λ��
	float fSAverage; // ƽ��λ��
	int nId; // ��¼Id
}

class JyChangedRecordStruct {
	short nGrade; // ���Լ���
	short nIndex; // ������������
	ArrayList<JyRecordStruct> RecordList; // �����������еĲ�����¼
}

class JyDataInfoStruct {
	short nGradeCount; // ���Լ���
	short nLoadGradeCount; // ���ؼ���
	short nUnloadGradeCount; // ж�ؼ���
	short nGradeTimeMax; // ��ļ��ص�����ʱʱ��
	float fSMin; // ��Сλ��ֵ
	float fSMax; // ���λ��ֵ
	float fQMax; // ����������ۺ���
	ArrayList<Short> LoadTimeList; // ����ʱ������
	ArrayList<Short> UnloadTimeList; // ж��ʱ������
	boolean[] SensorDown; // λ��ͨ���Ƿ�����
}

class JycFilePileParam {
	byte[] cTestSite; // ���Թ���
	byte[] cPileName; // ׮��
	int TestTime; // ������ʼʱ��
	int nTestObject; // ���Զ��� (׮/�ػ�)
	int nPileDiameter; // ׮�� mm
	int nPressUnit; // ���ص�λ kN/kPa
	double fBoardArea; // ѹ����� m*m
	double fTransRatio; // �û���
	double fPileLength; // ׮�� m

	int nCoordinateDirect; // �����귽�� (����/����)
	int nCoordinateMode; // ����ֵ���巽ʽ (�Զ�/�Զ���)
	int nCoordinateXMax; // ���������ֵ
	double fCoordinateYMin; // ��������Сֵ
	double fCoordinateYMax; // ���������ֵ

	int nReserve; // ��֤�ṹ�� 8 �ֽڶ���

	int[] LoadSampleGap; // ���ز������
	int[] UnloadSampleGap; // ж�ز������
	int[] ChannelUsed; // λ��ͨ����;
	int[] ChannelCalc; // �������ͨ��
	byte[] MZNo; // ê׮׮��

	public JycFilePileParam(String strProjectName, String strPileNo, JyDoc doc)
			throws Exception {
		cTestSite = strProjectName.getBytes("GB2312");
		cPileName = strPileNo.getBytes("GB2312");
		TestTime = (int) (doc.getJyData().get(0).RecordList.get(0).SampleTime
				.getTime() / 1000);
		nTestObject = doc.getIsGroundTest() ? 1 : 0;
		nPileDiameter = 0;
		nPressUnit = doc.getIsGroundTest() ? 1 : 0;
		fBoardArea = doc.getBoardArea();
		fTransRatio = 1D;
		fPileLength = 0;

		nCoordinateDirect = doc.getIsUp() ? 2 : 1;
		nCoordinateMode = 0;
		nCoordinateXMax = 1000;
		fCoordinateYMin = 0D;
		fCoordinateYMax = 1D;

		nReserve = 0;

		LoadSampleGap = new int[12];
		LoadSampleGap[0] = 0;

		int j = 1;
		for (int i = 0; (i < doc.getJyDataInfo().LoadTimeList.size())
				&& (j < 12); i++) {
			if ((i == 0) && (doc.getJyDataInfo().LoadTimeList.get(i) == 0))
				continue;

			if (i == 0)
				LoadSampleGap[j] = doc.getJyDataInfo().LoadTimeList.get(i);
			else
				LoadSampleGap[j] = doc.getJyDataInfo().LoadTimeList.get(i)
						- doc.getJyDataInfo().LoadTimeList.get(i - 1);

			j++;
		}

		for (int i = j; i < 12; i++) {
			LoadSampleGap[i] = LoadSampleGap[j - 1];
		}

		UnloadSampleGap = new int[12];
		UnloadSampleGap[0] = 0;
		j = 1;
		for (int i = 0; (i < doc.getJyDataInfo().UnloadTimeList.size())
				&& (j < 12); i++) {
			if ((i == 0) && (doc.getJyDataInfo().UnloadTimeList.get(i) == 0))
				continue;

			if (i == 0)
				UnloadSampleGap[j] = doc.getJyDataInfo().UnloadTimeList.get(i);
			else
				UnloadSampleGap[j] = doc.getJyDataInfo().UnloadTimeList.get(i)
						- doc.getJyDataInfo().UnloadTimeList.get(i - 1);

			j++;
		}

		for (int i = j; i < 12; i++) {
			UnloadSampleGap[i] = UnloadSampleGap[j - 1];
		}

		ChannelUsed = new int[12];
		ChannelCalc = new int[12];
		for (int i = 0; i < 12; i++) {
			ChannelUsed[i] = doc.getJyDataInfo().SensorDown[i] ? 1 : 0;
			ChannelCalc[i] = ChannelUsed[i];
		}

		MZNo = new byte[192];
	}

	public void saveToStream(ByteBuffer stream) {
		if (cTestSite.length > 31) {
			stream.put(cTestSite, 0, 31);
			stream.put((byte) 0);
		} else {
			stream.put(cTestSite);
			stream.put(new byte[32 - cTestSite.length]);
		}

		if (cPileName.length > 15) {
			stream.put(cPileName, 0, 15);
			stream.put((byte) 0);
		} else {
			stream.put(cPileName);
			stream.put(new byte[16 - cPileName.length]);
		}

		stream.putInt(TestTime);
		stream.putInt(nTestObject);
		stream.putInt(nPileDiameter);
		stream.putInt(nPressUnit);
		stream.putDouble(fBoardArea);
		stream.putDouble(fTransRatio);
		stream.putDouble(fPileLength);

		stream.putInt(nCoordinateDirect);
		stream.putInt(nCoordinateMode);
		stream.putInt(nCoordinateXMax);
		stream.putDouble(fCoordinateYMin);
		stream.putDouble(fCoordinateYMax);

		stream.putInt(nReserve);

		for (int i = 0; i < LoadSampleGap.length; i++)
			stream.putInt(LoadSampleGap[i]);
		for (int i = 0; i < UnloadSampleGap.length; i++)
			stream.putInt(UnloadSampleGap[i]);
		for (int i = 0; i < ChannelUsed.length; i++)
			stream.putInt(ChannelUsed[i]);
		for (int i = 0; i < ChannelCalc.length; i++)
			stream.putInt(ChannelCalc[i]);

		stream.put(MZNo, 0, 192);
	}
}

class JycFileOneData {
	int QGrade;
	int QDirect;
	int Q;
	int TimeGap;
	double[] s;
	double sAverage;

	public JycFileOneData() {
	}

	public JycFileOneData(int nGrade, JyRecordStruct jyRecord) {
		QGrade = nGrade;
		QDirect = jyRecord.nDirect;
		Q = (int) (jyRecord.fQGrade + 0.01f);
		TimeGap = 0;

		s = new double[12];
		for (int i = 0; i < 12; i++)
			s[i] = (jyRecord.fS[i]);

		sAverage = (jyRecord.fSAverage);
	}

	public void saveToStream(ByteBuffer stream) {
		stream.putInt(QGrade);
		stream.putInt(QDirect);
		stream.putInt(Q);
		stream.putInt(TimeGap);

		for (int i = 0; i < 12; i++)
			stream.putDouble(s[i]);

		stream.putDouble(sAverage);
	}
}

public class JyDoc {
	private ArrayList<JyGradeStruct> jyData;

	protected ArrayList<JyGradeStruct> getJyData() {
		return jyData;
	}

	private ArrayList<JyChangedRecordStruct> changedData;

	private JyDataInfoStruct jyDataInfo;

	protected JyDataInfoStruct getJyDataInfo() {
		return jyDataInfo;
	}

	private int imageWidth;

	public int getImageWidth() {
		return imageWidth;
	}

	public void setImageWidth(int value) {
		this.imageWidth = value;
	}

	private int imageHeight;

	public int getImageHeight() {
		return imageHeight;
	}

	public void setImageHeight(int value) {
		this.imageHeight = value;
	}

	private boolean isUp;

	public boolean getIsUp() {
		return isUp;
	}

	public void setIsUp(boolean value) {
		if (isGroundTest)
			isUp = false;
		else
			isUp = value;
	}

	private boolean isGroundTest;

	public boolean getIsGroundTest() {
		return isGroundTest;
	}

	public void setIsGroundTest(boolean value) {
		if (isGroundTest != value) {
			isGroundTest = value;

			if (isGroundTest) {
				isUp = false;
				kNTokPa();
			} else {
				kPaTokN();
			}
		}
	}

	private float boardArea;

	public float getBoardArea() {
		return boardArea;
	}

	public void setBoardArea(float value) {
		if (value > 0.001f) {
			if (isGroundTest) {
				kPaTokN();
				boardArea = value;
				kNTokPa();
			} else {
				boardArea = value;
			}
		}
	}

	private void kNTokPa() {
		if (boardArea <= 0.001f)
			return;

		jyDataInfo.fQMax /= boardArea;

		for (int i = 0; i < jyData.size(); i++) {
			JyGradeStruct jyGrade = jyData.get(i);
			for (int j = 0; j < jyGrade.RecordList.size(); j++) {
				JyRecordStruct jyRecord = jyGrade.RecordList.get(j);
				jyRecord.fQGrade /= boardArea;
				jyGrade.RecordList.set(j, jyRecord);
			}

			jyGrade.fQGrade /= boardArea;
			jyData.set(i, jyGrade);
		}
	}

	private void kPaTokN() {
		if (boardArea <= 0.001f)
			return;

		jyDataInfo.fQMax *= boardArea;

		for (int i = 0; i < jyData.size(); i++) {
			JyGradeStruct jyGrade = jyData.get(i);
			for (int j = 0; j < jyGrade.RecordList.size(); j++) {
				JyRecordStruct jyRecord = jyGrade.RecordList.get(j);
				jyRecord.fQGrade *= boardArea;
				jyGrade.RecordList.set(j, jyRecord);
			}

			jyGrade.fQGrade *= boardArea;
			jyData.set(i, jyGrade);
		}
	}

	private void insertToList(JyChangedRecordStruct data, JyRecordStruct record) {
		int i;
		for (i = 0; i < data.RecordList.size(); i++) {
			if (data.RecordList.get(i).nId > record.nId) {
				data.RecordList.add(i, record);
				return;
			}

			if (data.RecordList.get(i).nId == record.nId)
				return;
		}

		data.RecordList.add(i, record);
	}

	private void appendToChangedList(JyRecordStruct record1,
			JyRecordStruct record2) {
		int nIndex;
		for (nIndex = 0; nIndex < changedData.size(); nIndex++) {
			if (changedData.get(nIndex).nGrade > record1.nGrade)
				break;

			if ((changedData.get(nIndex).nGrade == record1.nGrade)
					&& (changedData.get(nIndex).nIndex > record1.nIndex))
				break;

			if ((changedData.get(nIndex).nGrade == record1.nGrade)
					&& (changedData.get(nIndex).nIndex == record1.nIndex)) {
				JyChangedRecordStruct Data = changedData.get(nIndex);
				insertToList(Data, record1);
				insertToList(Data, record2);

				changedData.set(nIndex, Data);
				return;
			}
		}

		JyChangedRecordStruct NewData = new JyChangedRecordStruct();
		NewData.nGrade = record1.nGrade;
		NewData.nIndex = record1.nIndex;
		NewData.RecordList = new ArrayList<JyRecordStruct>();
		insertToList(NewData, record1);
		insertToList(NewData, record2);

		changedData.add(nIndex, NewData);
	}

	private void appendToList(JyRecordStruct record) {
		boolean bFound = false;
		int nIndex;
		for (nIndex = 0; nIndex < jyData.size(); nIndex++) {
			JyGradeStruct jyGrade = jyData.get(nIndex);
			if (jyGrade.nGrade == record.nGrade) // �ҵ��ü�������
			{
				for (int i = 0; i < jyGrade.RecordList.size(); i++) {
					JyRecordStruct jyRecord = jyGrade.RecordList.get(i);
					if (jyRecord.nIndex == record.nIndex) // �ҵ��ôε�����
					{
						// �����޸ļ�¼��
						appendToChangedList(jyRecord, record);

						// ������������Ƕ�ǰ�ε��޸ģ����滻ԭ������
						if (jyRecord.nId < record.nId) {
							jyGrade.RecordList.set(i, record);
							jyData.set(nIndex, jyGrade);
							bFound = true;
							break;
						}
					} else if (jyRecord.nIndex > record.nIndex) // δ�ҵ��ô����ݣ������бȸô����ݸ����������
					{
						// ���ô����ݲ��뵽�˴�
						jyGrade.RecordList.add(i, record);
						jyData.set(nIndex, jyGrade);
						bFound = true;
						break;
					}
				}

				if (!bFound) {
					// ���ô�������ӵ��б�β��
					jyGrade.RecordList.add(record);
					jyData.set(nIndex, jyGrade);
					bFound = true;
				}
				break;
			} else if (jyGrade.nGrade > record.nGrade) // δ�ҵ��ü����ݣ������бȸü�������ļ���
			{
				break;
			}
		}

		if (!bFound) {
			// ����һ���µ����ݣ�����ӵ� nIndex ��
			JyGradeStruct jyGrade = new JyGradeStruct();
			jyGrade.RecordList = new ArrayList<JyRecordStruct>();
			jyGrade.nGrade = record.nGrade;
			jyGrade.nDirect = record.nDirect;
			jyGrade.fQGrade = record.fQGrade;
			jyGrade.RecordList.add(0, record);

			jyData.add(nIndex, jyGrade);
		}
	}

	private void makeJyData(int totalCount, String jsonString) throws Exception {

		//
		JSONTokener jsonTokener = new JSONTokener(jsonString);
		JSONArray jsonArray = (JSONArray) jsonTokener.nextValue();// ��׮��ϸ����

		float fSMin = Float.MAX_VALUE;
		float fSMax = Float.MIN_VALUE;

		for (int i = 0; i < totalCount; i++) {
			JSONObject object = jsonArray.getJSONObject(i);
			JyRecordStruct record = new JyRecordStruct();
			record.fS = new float[12];
			record.SampleTime = new Timestamp(0);

			record.nGrade = (short) object.getInt("Grade");
			record.nIndex = (short) object.getInt("SampleCount");
			record.SampleTime = Timestamp.valueOf(object
					.getString("SampleTime"));
			record.fQGrade = (float) object.getDouble("Loading");

			record.nDirect = (short) object.getInt("LoadDirect");
			record.nTimeCount = (short) object.getInt("TimeCount");
			record.fQ = (float) object.getDouble("RealLoading");

			try {
				record.fP = (float) object.getDouble("RealPress");
			} catch (JSONException e) {
				// fP��null
				record.fP = Float.MAX_VALUE;
			}

			record.fSAverage = (float) object.getDouble("SAverage");
			record.nId = object.getInt("Id");

			// 2011-09-26 ���������ǳ���� bug
			if ((record.nGrade == 0) && (record.nIndex == 1)) {
				record.nTimeCount = 0;
			}

			for (int xi = 0; xi < 12; xi++) {
				String sName = "S" + (xi + 1);
				String sString = object.getString(sName);
				if (sString.equalsIgnoreCase("null"))// �����n��������û��ֵ��������������ص�
				{
					record.fS[xi] = 0f;
					jyDataInfo.SensorDown[xi] = false;
				} else
					record.fS[xi] = Float.parseFloat(sString);
			}

			appendToList(record);

			if (fSMin > record.fSAverage)
				fSMin = record.fSAverage;
			if (fSMax < record.fSAverage)
				fSMax = record.fSAverage;
		}

		// ���� JyData ������������
		short nPrevTotalTime = 0;
		float fPrevSEnd = 0f;
		short nLoadGradeCount = -1;
		short nGradeTimeMax = Short.MIN_VALUE;
		float fQMax = Float.MIN_VALUE;

		for (int nIndex = 0; nIndex < jyData.size(); nIndex++) {
			JyGradeStruct jyGrade = jyData.get(nIndex);
			JyRecordStruct jyRecord = jyGrade.RecordList.get(jyGrade.RecordList
					.size() - 1);
			jyGrade.nTime = jyRecord.nTimeCount;
			jyGrade.nTotalTime = (short) (nPrevTotalTime + jyRecord.nTimeCount);
			jyGrade.fSEnd = jyRecord.fSAverage;
			jyGrade.fSInGrade = jyGrade.fSEnd - fPrevSEnd;
			jyData.set(nIndex, jyGrade);

			nPrevTotalTime = jyGrade.nTotalTime;
			fPrevSEnd = jyGrade.fSEnd;

			if ((nLoadGradeCount == -1) && (jyGrade.nDirect != 1)) {
				nLoadGradeCount = (short) nIndex;
			}

			if (nGradeTimeMax < jyGrade.nTime)
				nGradeTimeMax = jyGrade.nTime;
			if (fQMax < jyGrade.fQGrade)
				fQMax = jyGrade.fQGrade;
		}

		if (jyData.size() > 0) {
			jyDataInfo.nGradeCount = (short) jyData.size();
			jyDataInfo.nLoadGradeCount = (nLoadGradeCount >= 0) ? nLoadGradeCount
					: (short) jyData.size();
			jyDataInfo.nUnloadGradeCount = (short) (jyDataInfo.nGradeCount - jyDataInfo.nLoadGradeCount);
			jyDataInfo.nGradeTimeMax = nGradeTimeMax;
			jyDataInfo.fSMin = fSMin;
			jyDataInfo.fSMax = fSMax;
			jyDataInfo.fQMax = fQMax;

			for (int i = 0; i < jyDataInfo.nLoadGradeCount; i++) {
				JyGradeStruct jyGrade = jyData.get(i);
				for (int j = 0; j < jyGrade.RecordList.size(); j++) {
					boolean bFound = false;
					for (short n : jyDataInfo.LoadTimeList) {
						if (n == jyGrade.RecordList.get(j).nTimeCount) {
							bFound = true;
							break;
						}
					}

					if (!bFound) {
						jyDataInfo.LoadTimeList
								.add(jyGrade.RecordList.get(j).nTimeCount);
					}
				}
			}
			Collections.sort(jyDataInfo.LoadTimeList);

			for (int i = jyDataInfo.nLoadGradeCount; i < jyData.size(); i++) {
				JyGradeStruct jyGrade = jyData.get(i);
				for (int j = 0; j < jyGrade.RecordList.size(); j++) {
					boolean bFound = false;
					for (short n : jyDataInfo.UnloadTimeList) {
						if (n == jyGrade.RecordList.get(j).nTimeCount) {
							bFound = true;
							break;
						}
					}

					if (!bFound) {
						jyDataInfo.UnloadTimeList
								.add(jyGrade.RecordList.get(j).nTimeCount);
					}
				}
			}
			Collections.sort(jyDataInfo.UnloadTimeList);
		}
	}

	public JyDoc(int totalCount, String jsonString) throws Exception {
		isUp = false;
		isGroundTest = false;
		boardArea = 1F;
		imageWidth = 480;
		imageHeight = 640;

		jyData = new ArrayList<>();
		changedData = new ArrayList<>();
		jyDataInfo = new JyDataInfoStruct();
		jyDataInfo.LoadTimeList = new ArrayList<>();
		jyDataInfo.UnloadTimeList = new ArrayList<>();
		jyDataInfo.SensorDown = new boolean[12];
		for (int i = 0; i < jyDataInfo.SensorDown.length; i++) {
			jyDataInfo.SensorDown[i] = true;
		}

		makeJyData(totalCount, jsonString);
	}

	public void getQsImage(Canvas canvas) throws Exception {
		JyQs Qs = new JyQs(this);

		if (isGroundTest) {
			Qs.setTitle("p-s曲线");
			Qs.setScaleXString("p (kPa)");
			Qs.setScaleYString("位移 (mm)");
		} else if (isUp) {
			Qs.setIsUp(true);
			Qs.setTitle("U-s 曲线");
			Qs.setScaleXString("U (kN)");
			Qs.setScaleYString("s (mm)");
		}

		/**
		 * ����bitmap�����ض�����
		 */

		Log.v("MyTag", "QS������");
		canvas.setDrawFilter(new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG
				| Paint.LINEAR_TEXT_FLAG));
		Qs.OnDraw(canvas);

	}

	public void getSlgtImage(Canvas canvas) throws Exception {
		JySlgt slgt = new JySlgt(this);
		if (isGroundTest) {
			slgt.setTitle("s-lgt曲线");
			slgt.setScaleXString("t (min)");
			slgt.setScaleYString("s (mm)");
		} else if (isUp) {
			slgt.setIsUp(true);
			slgt.setTitle("s-lgt曲线");
			slgt.setScaleXString("t (min)");
			slgt.setScaleYString("s(mm)");
		}

		Log.v("MyTag", "Slgt 开始绘制");
		canvas.setDrawFilter(new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG
				| Paint.LINEAR_TEXT_FLAG));
		slgt.OnDraw(canvas);
	}

	public void getSlgQImage(Canvas canvas) throws Exception {
		JySlgQ slgQ = new JySlgQ(this);

		if (isGroundTest) {
			slgQ.setTitle("s-lgp曲线");
			slgQ.setScaleXString("p (kPa)");
			slgQ.setScaleYString("s (mm)");
		} else if (isUp) {
			slgQ.setIsUp(true);
			slgQ.setTitle("s-lgU 曲线");
			slgQ.setScaleXString("U (kN)");
			slgQ.setScaleYString("s (mm)");
		}

		Log.v("MyTag", "SlgQ������");
		canvas.setDrawFilter(new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG
				| Paint.LINEAR_TEXT_FLAG));
		slgQ.OnDraw(canvas);
	}

	public ArrayList<String> getGatherTable() {
		ArrayList<String> gatherTable = new ArrayList<String>(jyData.size() + 1);

		String strRow = "���,����,������ʱ,�ۼ���ʱ,��������,�ۼƳ���";
		gatherTable.add(strRow);

		for (int i = 0; i < jyData.size(); i++) {
			strRow = String.format("%1$d,%2$.0f,%3$d,%4$d,%5$.2f,%6$.2f",
					((jyData.get(0).fQGrade < 0.001f) ? i : (i + 1)),
					jyData.get(i).fQGrade, jyData.get(i).nTime,
					jyData.get(i).nTotalTime, jyData.get(i).fSInGrade,
					jyData.get(i).fSEnd);

			gatherTable.add(strRow);
		}

		return gatherTable;
	}

	public ArrayList<String> getSourceTable() {
		ArrayList<String> sourceTable = new ArrayList<String>(200);

		StringBuilder strRow = new StringBuilder(100);
		strRow.append("���ؼ���,���ۺ���,ʵ�����,ʵ����ѹ,��¼ʱ��,ʵ�ʼ��");
		for (int i = 0; i < 12; i++) {
			if (jyDataInfo.SensorDown[i]) {
				strRow.append(String.format(",λ��ͨ��%d", i + 1));
			}
		}
		strRow.append(",ƽ������");
		sourceTable.add(strRow.toString());

		Timestamp PrveSampleTime = new Timestamp(Long.MAX_VALUE);
		for (int i = 0; i < jyData.size(); i++) {
			JyGradeStruct jyGrade = jyData.get(i);

			for (int j = 0; j < jyGrade.RecordList.size(); j++) {
				strRow = new StringBuilder(100);
				JyRecordStruct jyRecord = jyGrade.RecordList.get(j);

				strRow.append(String.format("%d",
						(jyData.get(0).fQGrade < 0.001f) ? i : (i + 1)));
				strRow.append(String.format(",%.0f",
						(isGroundTest) ? jyRecord.fQGrade * boardArea
								: jyRecord.fQGrade));
				strRow.append(String.format(",%.0f", jyRecord.fQ));

				if (jyRecord.fP < Float.MAX_VALUE) {
					strRow.append(String.format(",%.2f", jyRecord.fP));
				} else {
					strRow.append(",-");
				}

				strRow.append(String.format(",%tT", jyRecord.SampleTime));

				if (PrveSampleTime.getTime() == Long.MAX_VALUE) {
					strRow.append(",0");
				} else {
					long timeSpan = (jyRecord.SampleTime.getTime() - PrveSampleTime
							.getTime()) / 60000;
					strRow.append(",");
					strRow.append(timeSpan);
				}

				for (int k = 0; k < 12; k++) {
					if (jyDataInfo.SensorDown[k]) {
						strRow.append(String.format(",%.2f", jyRecord.fS[k]));
					}
				}
				strRow.append(String.format(",%.2f", jyRecord.fSAverage));

				sourceTable.add(strRow.toString());

				PrveSampleTime = jyRecord.SampleTime;
			}
		}

		sourceTable.trimToSize();
		return sourceTable;
	}

	public ArrayList<String> getLoadTable() {
		ArrayList<String> loadTable = new ArrayList<String>(100);

		StringBuilder strRow = new StringBuilder(100);
		strRow.append("ʱ��");
		for (int i = 0; i < jyDataInfo.nLoadGradeCount; i++) {
			strRow.append(String.format(",%.0f", jyData.get(i).fQGrade));
		}
		loadTable.add(strRow.toString());

		for (int i = 0; i < jyDataInfo.LoadTimeList.size(); i++) {
			strRow = new StringBuilder(100);
			strRow.append(jyDataInfo.LoadTimeList.get(i));

			for (int j = 0; j < jyDataInfo.nLoadGradeCount; j++) {
				strRow.append(",");
				JyGradeStruct jyGrade = jyData.get(j);
				for (int n = 0; n < jyGrade.RecordList.size(); n++) {
					if (jyGrade.RecordList.get(n).nTimeCount == jyDataInfo.LoadTimeList
							.get(i)) {
						strRow.append(String.format("%.2f",
								jyGrade.RecordList.get(n).fSAverage));
						break;
					}
				}
			}

			loadTable.add(strRow.toString());
		}

		loadTable.trimToSize();
		return loadTable;
	}

	public ArrayList<String> getUnloadTable() {
		ArrayList<String> unloadTable = new ArrayList<String>(100);

		StringBuilder strRow = new StringBuilder(100);
		strRow.append("ʱ��");
		for (int i = jyDataInfo.nLoadGradeCount; i < jyData.size(); i++) {
			strRow.append(String.format(",%.0f", jyData.get(i).fQGrade));
		}
		unloadTable.add(strRow.toString());

		for (int i = 0; i < jyDataInfo.UnloadTimeList.size(); i++) {
			strRow = new StringBuilder(100);
			strRow.append(jyDataInfo.UnloadTimeList.get(i));

			for (int j = jyDataInfo.nLoadGradeCount; j < jyData.size(); j++) {
				strRow.append(",");
				JyGradeStruct jyGrade = jyData.get(j);
				for (int n = 0; n < jyGrade.RecordList.size(); n++) {
					if (jyGrade.RecordList.get(n).nTimeCount == jyDataInfo.UnloadTimeList
							.get(i)) {
						strRow.append(String.format("%.2f",
								jyGrade.RecordList.get(n).fSAverage));
						break;
					}
				}
			}

			unloadTable.add(strRow.toString());
		}

		unloadTable.trimToSize();
		return unloadTable;
	}

	public ArrayList<String> getChangeTable() {
		ArrayList<String> changeTable = new ArrayList<String>(100);

		StringBuilder strRow = new StringBuilder(100);
		strRow.append("���,״̬,���ۺ���,ʵ�����,ʵ����ѹ,��¼ʱ��");
		for (int i = 0; i < 12; i++) {
			if (jyDataInfo.SensorDown[i]) {
				strRow.append(String.format(",λ��ͨ��%d", i + 1));
			}
		}
		strRow.append(",ƽ������");
		changeTable.add(strRow.toString());

		for (int i = 0; i < changedData.size(); i++) {
			for (int j = 0; j < changedData.get(i).RecordList.size(); j++) {
				JyRecordStruct jyRecord = changedData.get(i).RecordList.get(j);

				strRow = new StringBuilder(100);
				strRow.append(i + 1);
				strRow.append((j == 0) ? ",�޸�ǰ" : ",�޸ĺ�");
				strRow.append(String.format(",%.0f",
						((isGroundTest) ? jyRecord.fQGrade * boardArea
								: jyRecord.fQGrade)));
				strRow.append(String.format(",%.0f", jyRecord.fQ));

				if (jyRecord.fP < Float.MAX_VALUE) {
					strRow.append(String.format(",%.2f", jyRecord.fP));
				} else {
					strRow.append(",-");
				}

				strRow.append(String.format(",%tT", jyRecord.SampleTime));

				for (int k = 0; k < 12; k++) {
					if (jyDataInfo.SensorDown[k]) {
						strRow.append(String.format(",%.2f", jyRecord.fS[k]));
					}
				}
				strRow.append(String.format(",%.2f", jyRecord.fSAverage));

				changeTable.add(strRow.toString());
			}
		}

		changeTable.trimToSize();
		return changeTable;
	}

	public byte[] getJycFile(String strProjectName, String strPileNo)
			throws Exception {
		// ��������ܼ�¼��
		int nRecordTotal = 0;
		for (int i = 0; i < jyData.size(); i++) {
			nRecordTotal += (jyData.get(i).RecordList.size());

			if (jyData.get(i).RecordList.get(0).nTimeCount != 0)
				nRecordTotal++;
		}
		if (jyData.get(0).fQGrade >= 0.01f)
			nRecordTotal++;

		if (nRecordTotal == 0)
			return (new byte[0]);

		ByteBuffer jycFile = ByteBuffer.allocate(5120 + nRecordTotal * 120);
		jycFile.order(ByteOrder.LITTLE_ENDIAN);

		// �洢��־�ַ�
		byte[] cFlag = new byte[] { (byte) '@', (byte) 'R', (byte) 'S',
				(byte) '-', (byte) 'J', (byte) 'Y', (byte) 'C', 0 };
		jycFile.put(cFlag);

		// �洢׮����
		jycFile.putInt(508);
		JycFilePileParam pileParam = new JycFilePileParam(strProjectName,
				strPileNo, this);
		pileParam.saveToStream(jycFile);

		// �洢��ǵ�
		jycFile.putInt(4);

		jycFile.putInt(nRecordTotal * 120 + 4);

		JycFileOneData OneData = new JycFileOneData();
		OneData.s = new double[12];
		OneData.QDirect = 1;
		int nGrade = 0;

		// ���û�г�ʼ�������ϳ�ʼ��
		if (jyData.get(0).fQGrade >= 0.01f) {
			OneData.saveToStream(jycFile);
			nGrade++;
		}

		for (int i = 0; i < jyData.size(); i++) {
			int nTimes = 0;
			OneData.TimeGap = 0;
			OneData.QGrade = nGrade;
			OneData.QDirect = jyData.get(i).nDirect;
			OneData.Q = (int) (jyData.get(i).fQGrade + 0.01f);

			// ����ü�û�г�ʼ���������ϸü��ĳ�ʼ����
			if (jyData.get(i).RecordList.get(0).nTimeCount != 0) {
				OneData.saveToStream(jycFile);
				nTimes++;
			}

			for (int j = 0; j < jyData.get(i).RecordList.size(); j++) {
				int PrevTime = OneData.TimeGap;
				OneData = new JycFileOneData(nGrade,
						jyData.get(i).RecordList.get(j));
				if (jyData.get(i).nDirect == 1) {
					OneData.TimeGap = (nTimes >= pileParam.LoadSampleGap.length) ? pileParam.LoadSampleGap[pileParam.LoadSampleGap.length - 1]
							: pileParam.LoadSampleGap[nTimes];
				} else {
					OneData.TimeGap = (nTimes >= pileParam.UnloadSampleGap.length) ? pileParam.UnloadSampleGap[pileParam.UnloadSampleGap.length - 1]
							: pileParam.UnloadSampleGap[nTimes];
				}

				OneData.TimeGap += PrevTime;
				OneData.saveToStream(jycFile);
				nTimes++;
			}

			nGrade++;
		}

		// �洢ԭʼ��¼ͷ
		jycFile.putInt(500);
		jycFile.put(new byte[496]);

		// �洢��չ׮����
		jycFile.putInt(260);
		jycFile.put(new byte[16]);

		byte[] cTestSite = strProjectName.getBytes("GB2312");
		if (cTestSite.length > 95) {
			jycFile.put(cTestSite, 0, 95);
			jycFile.put((byte) 0);
		} else {
			jycFile.put(cTestSite);
			jycFile.put(new byte[96 - cTestSite.length]);
		}

		jycFile.put(new byte[144]);

		return jycFile.array();
	}

	/**
	 * ��������Ϊ�Զ��壬��ԭ�����޹�
	 */
	// ��ȡ���һ�β����¼�
	public Timestamp getLastRecourdTimestamp() {
		JyGradeStruct jyGradeStruct = this.jyData.get(jyData.size() - 1);// ���һ������
		JyRecordStruct jyRecordStruct = jyGradeStruct.RecordList
				.get(jyGradeStruct.RecordList.size() - 1);// ���һ�������һ������
		return jyRecordStruct.SampleTime;
	}
}
